import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { v4 as uuidv4 } from 'uuid'
import type { AppWindow, App, AppCategory, AppWindowConfig } from '@/types/app'
import { getAppDetail, getAppList, getAppCategories, getFeaturedApps, getAppsByCategoryId } from '@/api/app'

export const useAppStore = defineStore('app', () => {
  // 窗口列表
  const windows = ref<AppWindow[]>([])
  
  // 最后一个活动窗口的z-index
  const lastZIndex = ref(100)
  
  // 应用分类
  const categories = ref<AppCategory[]>([])
  
  // 桌面应用
  const desktopApps = ref<App[]>([])

  // 已安装的应用
  const installedApps = ref<App[]>([])
  
  // 是否初始化完成
  const initialized = ref(false)
  
  // 获取打开的应用列表
  const openedApps = computed(() => {
    return windows.value
  })
  
  // 获取最小化的应用列表
  const minimizedApps = computed(() => {
    return windows.value
      .filter((window: AppWindow) => window.isMinimized)
      .map((window: AppWindow) => window.id)
  })
  
  // 获取窗口信息
  const getWindowById = (id: string) => {
    return windows.value.find((window: AppWindow) => window.id === id)
  }
  
  // 初始化应用数据
  const initAppData = async () => {
    if (initialized.value) return
    
    try {
      // 获取应用分类
      const categoryList = await getAppCategories()
      categories.value = categoryList.length > 0 ? categoryList : getDefaultCategories()

      // 获取精选应用列表作为桌面应用
      const featuredApps = await getFeaturedApps()
      desktopApps.value = featuredApps.length > 0 ? featuredApps : getDefaultApps()

      // 获取已安装应用
      try {
        const { data } = await getAppList()
        installedApps.value = data?.data || []
      } catch (error) {
        console.warn('获取已安装应用失败，使用默认应用', error)
        installedApps.value = getDefaultApps()
      }

      initialized.value = true
    } catch (error) {
      console.error('初始化应用数据失败，使用默认数据', error)
      
      // 使用默认数据
      categories.value = getDefaultCategories()
      desktopApps.value = getDefaultApps()
      installedApps.value = getDefaultApps()
      initialized.value = true
    }
  }

  // 获取默认分类
  const getDefaultCategories = (): AppCategory[] => {
    return [
      { id: 1, name: '办公工具', code: 'office', description: '提高办公效率的工具', sort: 1, status: 1 },
      { id: 2, name: '开发工具', code: 'development', description: '软件开发相关工具', sort: 2, status: 1 },
      { id: 3, name: '设计工具', code: 'design', description: '设计创作相关工具', sort: 3, status: 1 },
      { id: 4, name: '实用工具', code: 'utility', description: '日常使用的实用工具', sort: 4, status: 1 }
    ]
  }

  // 获取默认应用
  const getDefaultApps = (): App[] => {
    return [
      {
        id: 1,
        name: '文本编辑器',
        version: '1.0.0',
        description: '简单的文本编辑工具',
        icon: '/icons/notepad.png',
        categoryId: 1,
        developerId: 1,
        developerName: 'System',
        status: 1,
        isFeatured: true,
        config: {
          window: {
            width: 800,
            height: 600,
            resizable: true,
            maximizable: true,
            minimizable: true
          },
          permissions: []
        },
        component: 'TextEditorApp',
        storagePath: '/apps/notepad',
        views: 0,
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString()
      },
      {
        id: 2,
        name: '待办事项',
        version: '1.0.0',
        description: '任务管理工具',
        icon: '/icons/todo.png',
        categoryId: 1,
        developerId: 1,
        developerName: 'System',
        status: 1,
        isFeatured: true,
        config: {
          window: {
            width: 600,
            height: 500,
            resizable: true,
            maximizable: true,
            minimizable: true
          },
          permissions: []
        },
        component: 'TodoApp',
        storagePath: '/apps/todo',
        views: 0,
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString()
      },
      {
        id: 3,
        name: '图片查看器',
        version: '1.0.0',
        description: '图片浏览工具',
        icon: '/icons/image-viewer.png',
        categoryId: 4,
        developerId: 1,
        developerName: 'System',
        status: 1,
        isFeatured: true,
        config: {
          window: {
            width: 900,
            height: 700,
            resizable: true,
            maximizable: true,
            minimizable: true
          },
          permissions: []
        },
        component: 'ImageViewerApp',
        storagePath: '/apps/image-viewer',
        views: 0,
        createdAt: new Date().toISOString(),
        updatedAt: new Date().toISOString()
      }
    ]
  }

  // 根据分类获取应用
  const getAppsByCategory = async (categoryId: number) => {
    try {
      return await getAppsByCategoryId(categoryId)
    } catch (error) {
      console.error(`获取分类 ${categoryId} 下的应用失败`, error)
      return []
    }
  }
  
  // 打开应用
  const openApp = async (appId: number) => {
    try {
      // 检查应用是否已经打开
      const existingWindow = windows.value.find((window: AppWindow) => window.appId === appId)
      if (existingWindow) {
        // 如果已经打开但被最小化，则恢复窗口
        if (existingWindow.isMinimized) {
          restoreApp(existingWindow.id)
        } else {
          // 否则激活窗口
          activateApp(existingWindow.id)
        }
        return existingWindow.id
      }
      
      // 尝试获取应用详情
      let appInfo: App
      
      try {
        // 从API获取应用详情
        const appDetail = await getAppDetail(appId)
        appInfo = appDetail.data
      } catch (error) {
        // 如果API请求失败，尝试从本地应用列表获取
        console.warn('获取应用详情失败，尝试从本地应用列表获取', error)
        const localApp = [...desktopApps.value, ...installedApps.value].find(app => app.id === appId)
        
        if (!localApp) {
          throw new Error('找不到指定的应用')
        }
        
        appInfo = localApp
      }
      
      // 窗口ID
      const windowId = uuidv4()
      
      // 应用窗口配置
      const windowConfig: AppWindowConfig = appInfo.config?.window || {
        width: 800,
        height: 600,
        minWidth: 320,
        minHeight: 240,
        resizable: true,
        maximizable: true,
        minimizable: true
      }
      
      // 获取最佳窗口位置
      const { x, y } = getBestWindowPosition(windowConfig.width, windowConfig.height)
      
      // 创建新窗口
      const newWindow: AppWindow = {
        id: windowId,
        appId: appInfo.id,
        title: appInfo.name,
        icon: appInfo.icon,
        component: appInfo.component,
        x,
        y,
        width: windowConfig.width,
        height: windowConfig.height,
        minWidth: windowConfig.minWidth,
        minHeight: windowConfig.minHeight,
        isActive: true,
        isMinimized: false,
        isMaximized: false,
        resizable: windowConfig.resizable,
        maximizable: windowConfig.maximizable,
        minimizable: windowConfig.minimizable,
        zIndex: lastZIndex.value + 1
      }
      
      // 更新最后的z-index
      lastZIndex.value = newWindow.zIndex
      
      // 将其他窗口设置为非活动状态
      windows.value.forEach(window => {
        window.isActive = false
      })
      
      // 添加新窗口
      windows.value.push(newWindow)
      
      return windowId
    } catch (error) {
      console.error('打开应用失败:', error)
      throw error
    }
  }
  
  // 获取最佳窗口位置
  const getBestWindowPosition = (width: number, height: number) => {
    // 获取视口大小
    const viewportWidth = window.innerWidth
    const viewportHeight = window.innerHeight
    
    // 默认位置
    let x = (viewportWidth - width) / 2
    let y = (viewportHeight - height) / 2
    
    // 如果有其他窗口，则错开位置
    if (windows.value.length > 0) {
      const offset = windows.value.length * 20
      x += offset
      y += offset
      
      // 确保窗口不会超出视口
      if (x + width > viewportWidth) {
        x = 20
      }
      if (y + height > viewportHeight) {
        y = 20
      }
    }
    
    return { x, y }
  }
  
  // 激活窗口
  const activateApp = (windowId: string) => {
    const window = getWindowById(windowId)
    if (!window) return
    
    // 将其他窗口设置为非活动状态
    windows.value.forEach(w => {
      w.isActive = false
    })
    
    // 激活当前窗口
    window.isActive = true
    window.isMinimized = false
    
    // 更新z-index
    lastZIndex.value += 1
    window.zIndex = lastZIndex.value
  }
  
  // 最小化窗口
  const minimizeApp = (windowId: string) => {
    const window = getWindowById(windowId)
    if (!window) return
    
    window.isMinimized = true
    window.isActive = false
    
    // 激活下一个可见的窗口
    const nextWindow = windows.value
      .filter(w => !w.isMinimized && w.id !== windowId)
      .sort((a, b) => b.zIndex - a.zIndex)[0]
    
    if (nextWindow) {
      activateApp(nextWindow.id)
    }
  }
  
  // 最大化窗口
  const maximizeApp = (windowId: string) => {
    const appWindow = getWindowById(windowId)
    if (!appWindow || !appWindow.maximizable) return
    
    // 保存原始大小和位置
    if (!appWindow.isMaximized) {
      appWindow.originalState = {
        x: appWindow.x,
        y: appWindow.y,
        width: appWindow.width,
        height: appWindow.height
      }
    }
    
    appWindow.isMaximized = true
    appWindow.x = 0
    appWindow.y = 0
    appWindow.width = window.innerWidth
    appWindow.height = window.innerHeight - 60 // 减去任务栏高度
    
    activateApp(windowId)
  }
  
  // 恢复最大化窗口
  const restoreMaximizedApp = (windowId: string) => {
    const window = getWindowById(windowId)
    if (!window || !window.isMaximized || !window.originalState) return
    
    window.isMaximized = false
    window.x = window.originalState.x
    window.y = window.originalState.y
    window.width = window.originalState.width
    window.height = window.originalState.height
    
    activateApp(windowId)
  }
  
  // 恢复窗口
  const restoreApp = (windowId: string) => {
    const window = getWindowById(windowId)
    if (!window) return
    
    window.isMinimized = false
    activateApp(windowId)
  }
  
  // 关闭窗口
  const closeApp = async (windowId: string) => {
    const windowIndex = windows.value.findIndex(w => w.id === windowId)
    if (windowIndex === -1) return
    
    const window = windows.value[windowIndex]
    
    // 移除窗口
    windows.value.splice(windowIndex, 1)
    
    // 激活下一个可见的窗口
    const nextWindow = windows.value
      .filter(w => !w.isMinimized)
      .sort((a, b) => b.zIndex - a.zIndex)[0]
    
    if (nextWindow) {
      activateApp(nextWindow.id)
    }
  }
  
  // 更新窗口位置
  const updateWindowPosition = (windowId: string, x: number, y: number) => {
    const window = getWindowById(windowId)
    if (!window || window.isMaximized) return
    
    window.x = x
    window.y = y
  }
  
  // 更新窗口大小
  const updateWindowSize = (windowId: string, width: number, height: number) => {
    const window = getWindowById(windowId)
    if (!window || window.isMaximized || !window.resizable) return
    
    // 确保不小于最小尺寸
    window.width = Math.max(width, window.minWidth || 320)
    window.height = Math.max(height, window.minHeight || 240)
  }
  
  // 关闭所有窗口
  const closeAllApps = async () => {
    // 复制窗口列表，因为关闭过程中会修改原列表
    const windowsToClose = [...windows.value]
    
    // 依次关闭所有窗口
    for (const window of windowsToClose) {
      await closeApp(window.id)
    }
  }

  // 平铺所有窗口
  const tileWindows = () => {
    const visibleWindows = windows.value.filter(w => !w.isMinimized)
    if (visibleWindows.length === 0) return
    
    const viewportWidth = window.innerWidth
    const viewportHeight = window.innerHeight
    
    // 计算网格大小
    const count = visibleWindows.length
    const cols = Math.ceil(Math.sqrt(count))
    const rows = Math.ceil(count / cols)
    
    // 计算单个窗口大小
    const width = Math.floor(viewportWidth / cols)
    const height = Math.floor(viewportHeight / rows)
    
    // 调整所有窗口
    visibleWindows.forEach((window, index) => {
      const row = Math.floor(index / cols)
      const col = index % cols
      
      window.isMaximized = false
      window.x = col * width
      window.y = row * height
      window.width = width
      window.height = height
    })
  }

  // 层叠所有窗口
  const cascadeWindows = () => {
    const visibleWindows = windows.value.filter(w => !w.isMinimized)
    if (visibleWindows.length === 0) return
    
    const offset = 30
    const baseWidth = Math.min(800, window.innerWidth * 0.8)
    const baseHeight = Math.min(600, window.innerHeight * 0.8)
    
    visibleWindows.forEach((window, index) => {
      window.isMaximized = false
      window.x = offset * index
      window.y = offset * index
      window.width = baseWidth
      window.height = baseHeight
    })
  }

  // 窗口布局类型
  type WindowLayout = 'tile' | 'cascade'

  // 设置窗口布局
  const setWindowLayout = (layout: WindowLayout) => {
    switch (layout) {
      case 'tile':
        tileWindows()
        break
      case 'cascade':
        cascadeWindows()
        break
    }
  }

  // 安装应用
  const installApp = async (app: App) => {
    // 检查应用是否已安装
    const existingApp = installedApps.value.find(a => a.id === app.id)
    if (!existingApp) {
      // TODO: 调用后端 API 安装应用
      try {
        // 添加到已安装列表
        installedApps.value.push(app)
        
        // 如果是精选应用，添加到桌面
        if (app.isFeatured) {
          addToDesktop(app)
        }
        
        return true
      } catch (error) {
        console.error('安装应用失败:', error)
        throw error
      }
    }
    return false
  }

  // 卸载应用
  const uninstallApp = async (appId: number) => {
    try {
      // TODO: 调用后端 API 卸载应用
      
      // 关闭应用窗口
      const appWindow = windows.value.find(w => w.appId === appId)
      if (appWindow) {
        await closeApp(appWindow.id)
      }

      // 从已安装列表中移除
      const index = installedApps.value.findIndex(a => a.id === appId)
      if (index !== -1) {
        installedApps.value.splice(index, 1)
      }

      // 从桌面移除
      removeFromDesktop(appId)
      
      return true
    } catch (error) {
      console.error('卸载应用失败:', error)
      throw error
    }
  }

  // 添加到桌面
  const addToDesktop = (app: App) => {
    // 检查应用是否已在桌面
    const existingApp = desktopApps.value.find(a => a.id === app.id)
    if (!existingApp) {
      desktopApps.value.push(app)
      return true
    }
    return false
  }

  // 从桌面移除
  const removeFromDesktop = (appId: number) => {
    const index = desktopApps.value.findIndex(a => a.id === appId)
    if (index !== -1) {
      desktopApps.value.splice(index, 1)
      return true
    }
    return false
  }

  // 更新应用
  const updateApp = async (appId: number) => {
    try {
      // TODO: 调用后端 API 更新应用
      
      // 关闭应用窗口
      const appWindow = windows.value.find(w => w.appId === appId)
      if (appWindow) {
        await closeApp(appWindow.id)
      }

      // 更新已安装列表中的应用信息
      const app = installedApps.value.find(a => a.id === appId)
      if (app) {
        // TODO: 获取最新的应用信息并更新
      }

      return true
    } catch (error) {
      console.error('更新应用失败:', error)
      throw error
    }
  }

  // 获取应用运行状态
  const getAppStatus = (appId: number) => {
    const appWindow = windows.value.find(w => w.appId === appId)
    if (!appWindow) return 'closed'
    if (appWindow.isMinimized) return 'minimized'
    if (appWindow.isMaximized) return 'maximized'
    return 'running'
  }

  // 检查应用是否已安装
  const isAppInstalled = (appId: number) => {
    return installedApps.value.some(app => app.id === appId)
  }

  // 检查应用是否在桌面
  const isAppOnDesktop = (appId: number) => {
    return desktopApps.value.some(app => app.id === appId)
  }

  // 获取应用配置
  const getAppConfig = (appId: number) => {
    const app = installedApps.value.find(a => a.id === appId)
    return app?.config || null
  }

  // 保存应用配置
  const saveAppConfig = async (appId: number, config: any) => {
    try {
      // TODO: 调用后端 API 保存应用配置
      
      // 更新本地应用配置
      const app = installedApps.value.find(a => a.id === appId)
      if (app) {
        app.config = { ...app.config, ...config }
      }

      return true
    } catch (error) {
      console.error('保存应用配置失败:', error)
      throw error
    }
  }

  // 重置应用配置
  const resetAppConfig = async (appId: number) => {
    try {
      // TODO: 调用后端 API 重置应用配置
      
      // 更新本地应用配置
      const app = installedApps.value.find(a => a.id === appId)
      if (app) {
        app.config = undefined
      }

      return true
    } catch (error) {
      console.error('重置应用配置失败:', error)
      throw error
    }
  }

  return {
    windows,
    categories,
    desktopApps,
    installedApps,
    openedApps,
    minimizedApps,
    getWindowById,
    initAppData,
    getAppsByCategory,
    openApp,
    activateApp,
    closeApp,
    minimizeApp,
    maximizeApp,
    restoreMaximizedApp,
    restoreApp,
    updateWindowPosition,
    updateWindowSize,
    closeAllApps,
    installApp,
    uninstallApp,
    addToDesktop,
    removeFromDesktop,
    updateApp,
    getAppStatus,
    isAppInstalled,
    isAppOnDesktop,
    getAppConfig,
    saveAppConfig,
    resetAppConfig,
    tileWindows,
    cascadeWindows,
    setWindowLayout
  }
}, {
  persist: {
    paths: ['desktopApps', 'installedApps']
  }
}) 